package com.example.tongyao.system.controller;


import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.tongyao.common.SuperController;
import com.example.tongyao.system.entity.*;
import com.example.tongyao.system.message.SystemMessage;
import com.example.tongyao.system.service.*;
import com.example.tongyao.utils.*;
import com.example.tongyao.utils.token.UserUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author tongyao
 * @since 2021-08-15
 */
@RestController
@Api(tags = "系统_用户前端控制器")
@RequestMapping("/system/sys-user")
public class SysUserController extends SuperController {


    @Resource
    private ISysUserService iSysUserService;

    @Resource
    private ISysDeptService iSysDeptService;

    @Resource
    private ISysUserRoleService iSysUserRoleService;

    @Resource
    private ISysUserDeptService iSysUserDeptService;

    @Resource
    private ISysUserJobService iSysUserJobService;

    /**
     * 根据当前用户的部门id查询子部门树
     * @return
     */
    @ApiOperation(
            value = "查询部门树",
            notes = "根据左侧部门树，用于点击查询右侧用户信息",
            httpMethod = "GET")
    @GetMapping(value = "/deptTree" , produces = {MediaType.APPLICATION_JSON_VALUE})
    public DataResult deptTree() {
        /**
         * 缺少数据范围操作 注
         */
        SysUser sysUser = (SysUser) UserUtils.getUserInfo();

        int i = 0;
        List<SysDept> sysDeptList = SysDeptController.showTree(iSysDeptService.list());

        return DataResult.setSuccess(sysDeptList);
    }

    /**
     * 分页根据部门查询用户列表
     * @return
     */
    @ApiOperation(
            value = "查询用户",
            notes = "根据左侧部门树，点击事件分页查询用户信息",
            httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deptId",value = "部门deptId",required = true),
            @ApiImplicitParam(name = "userName",value = "用户名称"),
            @ApiImplicitParam(name = "pageNo",value = "当前页数",defaultValue = "1"),
            @ApiImplicitParam(name = "pageSize",value = "显示条数",defaultValue = "10"),
            @ApiImplicitParam(name = "sortBy",value = "排序字段（多个以英文逗号拼接）",defaultValue = "create_time"),
            @ApiImplicitParam(name = "order",value = "排序类型",defaultValue = "asc")
    })
    @GetMapping(value = "/page/{deptId}" , produces = {MediaType.APPLICATION_JSON_VALUE})
    public DataResult page(@PathVariable(value="deptId") String deptId,
                               @RequestParam(required = false) String userName,
                               @RequestParam(defaultValue = "1") int pageNo,
                               @RequestParam(defaultValue = "10") int pageSize,
                               @RequestParam(defaultValue = "create_time") String sortBy,
                               @RequestParam(defaultValue = "asc") String order) {

        //@RequestParam required的默认值是true，有默认值可以不写required
        //@ApiImplicitParam required的默认值是false，有默认值可以不写required

        /*PageUtil<SysUser> page = new PageUtil<>(pageNo,pageSize,sortBy,order);
        Map<String, Object> params = TongYaoUtils.toObjectMap(page);
        params.put("deptId",deptId);
        params.put("userName",userName);


        List<SysUser> list = iSysUserService.userPage(params);
        page.setPage(list,iSysUserService.userPageCount(params),pageNo);*/



        //3代自定义SQL并分页 任选一个
        Map<String, Object> params = new HashMap<>();
        params.put("deptId",deptId);
        params.put("userName",userName);

        params.put("sortBy",sortBy);
        params.put("order",order);

        Page<Map<String,Object>> page = new Page<>(pageNo,pageSize);
        IPage<SysUser> iPage = iSysUserService.userPage(page,params);

        return DataResult.setSuccess(iPage);
    }



    @ApiOperation(
            value = "添加用户",
            notes = "添加一个用户",
            httpMethod = "POST")
    @PostMapping(value = "/save" , produces = {MediaType.APPLICATION_JSON_VALUE})
    public DataResult save(@Valid @RequestBody(required = true) SysUser sysUser) {

        //这块是个问题
        if(sysUser.getUsername() == null || sysUser.getUsername().equals("")){
            throw new RuntimeException("用户账号不能为空！");
        }

        SysUser user = (SysUser) UserUtils.getUserInfo();

        //判断用户名是否存在
        userExist(sysUser.getUsername());

        //用户密码加密，考虑从系统配置里获取默认密码
        SysConfig sysConfig = iSysConfigService.getConfigByKey("default_password");

        sysUser.setPassword(sysConfig.getConfigValue());
        sysUser.setIdType(2);
        sysUser.setEnabled(true);
        sysUser.setAccountNonLocked(true);
        sysUser.setAccountNonExpired(true);
        sysUser.setCredentialsNonExpired(true);
        sysUser.setDelFlag(1);

        sysUser.setCreateBy(user.getUserId());
        sysUser.setCreateTime(DateUtils.getDateTime());
        reuslt = iSysUserService.save(sysUser);
        if(!reuslt){
            throw new RuntimeException("用户添加失败！");
        }



        //循环遍历添加部门
        SysUserDept sysUserDept;
        String[] deptIds = sysUser.getDeptId().split(",");
        for (String deptId: deptIds) {
            sysUserDept = new SysUserDept();
            sysUserDept.setUserId(sysUser.getUserId());
            sysUserDept.setDeptId(deptId);
            reuslt = iSysUserDeptService.save(sysUserDept);
            if(!reuslt){
                break;
            }
        }
        if(!reuslt){
            throw new RuntimeException("用户部门关系添加失败！");
        }

        //循环遍历添加岗位
        SysUserJob sysUserJob;
        String[] jobIds = sysUser.getJobId().split(",");
        for (String jobId: jobIds) {
            sysUserJob = new SysUserJob();
            sysUserJob.setUserId(sysUser.getUserId());
            sysUserJob.setJobId(jobId);
            reuslt = iSysUserJobService.save(sysUserJob);
            if(!reuslt){
                break;
            }
        }
        if(!reuslt){
            throw new RuntimeException("用户岗位关系添加失败！");
        }


        return DataResult.setSuccess(null);
    }

    @ApiOperation(
            value = "编辑用户",
            notes = "编辑一个用户",
            httpMethod = "PUT")
    @PutMapping(value = "/edit" , produces = {MediaType.APPLICATION_JSON_VALUE})
    public DataResult edit(@Valid @RequestBody(required = true) SysUser sysUser) {

        //这块是个问题！！！！！！！！！！！！！！！！！！！
        if(StringUtils.isBlank(sysUser.getUserId())){
            throw new RuntimeException("用户编号不能为空！");
        }

        //String userName = UserUtils.getUserName();
        SysUser user = (SysUser) UserUtils.getUserInfo();

        //验证修改的昵称与当前昵称是否一致
        if(!user.getUsername().equals(sysUser.getUsername())){
            //判断用户名是否存在
            userExist(sysUser.getUsername());
        }

        //更新用户
        sysUser.setPassword(null);
        sysUser.setModifyBy(user.getUserId());
        sysUser.setCreateTime(DateUtils.getDateTime());

        reuslt = iSysUserService.updateById(sysUser);
        if(!reuslt){
            throw new RuntimeException("用户更新失败！");
        }

        //删除用户部门关系数据
        map = new HashMap<>();
        map.put("user_id",sysUser.getUserId());
        reuslt = iSysUserDeptService.removeByMap(map);
        if(!reuslt){
            throw new RuntimeException("用户部门关系删除失败！");
        }

        //循环遍历添加部门
        SysUserDept sysUserDept;
        String[] deptIds = sysUser.getDeptId().split(",");
        for (String deptId: deptIds) {
            sysUserDept = new SysUserDept();
            sysUserDept.setUserId(sysUser.getUserId());
            sysUserDept.setDeptId(deptId);
            reuslt = iSysUserDeptService.save(sysUserDept);
            if(!reuslt){
                break;
            }
        }
        if(!reuslt){
            throw new RuntimeException("用户部门关系添加失败！");
        }

        //删除用户岗位关系数据
        map = new HashMap<>();
        map.put("user_id",sysUser.getUserId());
        reuslt = iSysUserJobService.removeByMap(map);
        if(!reuslt){
            throw new RuntimeException("用户岗位关系删除失败！");
        }

        //循环遍历添加岗位
        SysUserJob sysUserJob;
        String[] jobIds = sysUser.getJobId().split(",");
        for (String jobId: jobIds) {
            sysUserJob = new SysUserJob();
            sysUserJob.setUserId(sysUser.getUserId());
            sysUserJob.setJobId(jobId);
            reuslt = iSysUserJobService.save(sysUserJob);
            if(!reuslt){
                break;
            }
        }
        if(!reuslt){
            throw new RuntimeException("用户岗位关系添加失败！");
        }

        return null;
    }

    @ApiOperation(
            value = "分配角色",
            notes = "给用户分配一个或多个角色",
            httpMethod = "PUT")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId",value = "用户编号",required = true),
            @ApiImplicitParam(name = "roleId",value = "角色编号，多个以英文逗号拼接",required = true)
    })
    @PutMapping(value = "/allotRole" , produces = {MediaType.APPLICATION_JSON_VALUE})
    public DataResult allotRole(
            @RequestParam String userId,
            @RequestParam String roleId
    ) {

        //删除用户角色关系
        map = new HashMap<>();
        map.put("user_id",userId);
        reuslt = iSysUserRoleService.removeByMap(map);

        //循环遍历添加用户角色
        SysUserRole sysUserRole;
        String[] roleIds = roleId.split(",");
        for (String roleIdItem: roleIds) {
            sysUserRole = new SysUserRole();
            sysUserRole.setUserId(userId);
            sysUserRole.setRoleId(roleIdItem);
            reuslt = iSysUserRoleService.save(sysUserRole);
            if(!reuslt){
                break;
            }
        }
        if(!reuslt){
            throw new RuntimeException("用户角色关系添加失败！");
        }

        return DataResult.setSuccess(null);
    }

    @ApiOperation(
            value = "更改状态",
            notes = "更改用户的启用禁用状态",
            httpMethod = "PUT")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId",value = "用户编号",required = true),
            @ApiImplicitParam(name = "state",value = "账户状态（true为启用，false为禁用）",required = true)
    })
    @PutMapping(value = "/changeState" , produces = {MediaType.APPLICATION_JSON_VALUE})
    public DataResult changeState(
            @RequestParam String userId,
            @RequestParam boolean state
    ){

        SysUser user = (SysUser) UserUtils.getUserInfo();

        SysUser sysUser = new SysUser();
        sysUser.setEnabled(state);
        sysUser.setUserId(userId);

        sysUser.setAccountNonExpired(true);
        sysUser.setAccountNonLocked(true);
        sysUser.setCredentialsNonExpired(true);
        sysUser.setModifyBy(user.getUserId());
        sysUser.setModifyTime(DateUtils.getDateTime());

        reuslt = iSysUserService.updateById(sysUser);
        if(!reuslt){
            throw new RuntimeException("用户状态更新失败！");
        }

        return DataResult.setSuccess(null);
    }

    @ApiOperation(
            value = "删除用户",
            notes = "删除一个或多个用户",
            httpMethod = "DELETE")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId",value = "用户编号，多个以英文逗号拼接",required = true),
    })
    @DeleteMapping(value = "/delete" , produces = {MediaType.APPLICATION_JSON_VALUE})
    public DataResult delete(@RequestParam String userId){
        reuslt = iSysUserService.deleteUserByUserId(userId);
        if(!reuslt){
            throw new RuntimeException("用户删除失败！");
        }

        return DataResult.setSuccess(null);
    }

    @ApiOperation(
            value = "修改密码",
            notes = "修改用户的密码",
            httpMethod = "PUT")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId",value = "用户编号，多个以英文逗号拼接",required = true),
    })
    @PutMapping(value = "/editPass" , produces = {MediaType.APPLICATION_JSON_VALUE})
    public DataResult editPass(@RequestParam String oldPass,
                               @RequestParam String newPass){

        SysUser user = (SysUser) UserUtils.getUserInfo();
        if(!user.getPassword().equals(oldPass)){
            throw new RuntimeException("旧密码与当前密码不一致！");
        }

        LambdaUpdateWrapper<SysUser> sysUserLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        sysUserLambdaUpdateWrapper.set(SysUser::getPassword,newPass);
        sysUserLambdaUpdateWrapper.eq(SysUser::getUserId,user.getUserId());

        reuslt = iSysUserService.update(sysUserLambdaUpdateWrapper);
        if(!reuslt){
            throw new RuntimeException(
                    SystemMessage.passWord+
                            SystemMessage.update+
                            SystemMessage.fail+
                            SystemMessage.a);
        }

        return DataResult.setSuccess(null);
    }
    @ApiOperation(
            value = "重置密码",
            notes = "重置用户密码为默认密码",
            httpMethod = "PUT")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId",value = "用户编号，多个以英文逗号拼接",required = true),
    })
    @PutMapping(value = "/reset" , produces = {MediaType.APPLICATION_JSON_VALUE})
    public DataResult reset(@RequestParam String userId){
        SysConfig sysConfig = iSysConfigService.getConfigByKey("default_password");
        reuslt = iSysUserService.resetPasswordByUserId(userId,sysConfig.getConfigValue());
        if(!reuslt){
            throw new RuntimeException("用户密码重置失败！");
        }

        return DataResult.setSuccess(null);
    }

    /**
     * 判断用户名是否存在
     * @param code
     * @return
     */
    public void userExist(String code){
        int count = commonService.getCount("sys_user","username = '"+code+"' and del_flag = 1");
        if(count > 0){
            throw new RuntimeException(code+" 用户名已存在！");
        }
    }

    /**
     * 查询用户信息
     * @param username
     * @return
     */
    public SysUser userQuery(String username){
        map = new HashMap<>();
        map.put("username",username);
        map.put("del_flag","1");
        List<SysUser> sysUserList = iSysUserService.listByMap(map);
        if(sysUserList == null || sysUserList.size() <= 0){
            return null;
        }
        return sysUserList.get(0);
    }
}
